home *** CD-ROM | disk | FTP | other *** search
- { Thanks to Marshall Brain for the original code for this routine.
-
- These routines provide a method for Turbo Pascal programs to trap MS-DOS
- interrupt 24. INT 24 is called by DOS when a 'critical error' occurs, and
- it normally prints the familiar "Abort, Retry, Ignore?" message.
-
- With the INT 24 handler installed, errors of this type will be passed on to
- Turbo Pascal as an error. If I/O checking is on, this will cause a program
- crash. If I/O checking is off, IOResult will return an error code. The
- global variable INT24Err will be true if an INT 24 error has occurred. The
- variable INT24ErrorCode will contain the INT 24 error code as given by DOS.
- These errors can be found in the DOS Technical Reference Manual. They
- correspond to the error codes returned by the function INT24Result, with an
- offset of 256. INT24Result is used like IOResult, and calls IOResult. It
- then checks INT24Err, and if it is true, returns INT24ErrorCode+256 instead.
-
- In most cases, INT24Result should be used, because INT24Err must be set back
- to false, and because DOS sometimes restores its normal INT 24 handler after
- an error.
-
-
- Note that Turbo's normal IOResult codes for MS-DOS DO NOT correspond to the
- I/O error numbers given in Appendix I of the Turbo Pascal manual, or to the
- error codes given in the I/O error nn, PC=aaaa/Program aborted message. Here
- is a table of the correspondence (all numbers in hexadecimal):
-
- IOResult Turbo error
- -------- -------------------------------------------------
- 00 00 none
- 01 90 record length mismatch
- 02 01 file does not exist
- 03 F1 directory is full
- 04 FF file disappeared
- 05 02 file not open for input
- 06 03 file not open for output
- 07 99 unexpected end of file
- 08 F0 disk write error
- 09 10 error in numeric format
- 0A 99 unexpected end of file
- 0B F2 file size overflow
- 0C 99 unexpected end of file
- 0D F0 disk write error
- 0E 91 seek beyond end of file
- 0F 04 file not open
- 10 20 operation not allowed on a logical device
- 11 21 not allowed in direct mode
- 12 22 assign to standard files is not allowed
-
- - Bela Lubkin
- }
-
- Const
- INT24Err: Boolean=False;
- INT24ErrCode: Byte=0;
- OldINT24: Array [1..2] Of Integer=(0,0);
-
- Var
- RegisterSet: Record Case Integer Of
- 1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
- 2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
- End;
-
- Procedure INT24;
- Begin
- {To understand this routine, you will need to read}
- {the description on Interrupt 24 in the DOS manual}
- Inline
- ($83/$C4/$0A); {ADD SP,0AH Discard first 5 words on stack}
- INT24Err:=True;
- Inline
- ($89/$F8/ {MOV AX,DI Get INT 24 error code}
- $2E/$A2/INT24ErrCode/ {MOV CS:[INT24ErrCode],AL}
- $58/ {POP AX Pop all registers}
- $B0/$FF/ {MOV AL,0FFH Set error flag}
- $5B/ {POP BX}
- $59/ {POP CX}
- $5A/ {POP DX}
- $5E/ {POP SI}
- $5F/ {POP DI}
- $5D/ {POP BP}
- $1F/ {POP DS}
- $07/ {POP ES}
- $CF); {IRET Return to next instruction}
- End;
-
- Procedure INT24On; {Enable INT 24 trapping}
- Begin
- INT24Err:=False;
- With RegisterSet Do
- Begin
- AX:=$3524;
- MsDos(RegisterSet);
- If (OldINT24[1] Or OldINT24[2])=0 Then
- Begin
- OldINT24[1]:=ES;
- OldINT24[2]:=BX;
- End;
- DS:=CSeg;
- DX:=Ofs(INT24);
- AX:=$2524;
- MsDos(RegisterSet);
- End;
- End;
-
- Procedure INT24Off; {Disable INT 24 trapping. Should be done at the end
- of the program, if you plan to be running the program
- from within Turbo.}
- Begin
- INT24Err:=False;
- If OldINT24[1]<>0 Then
- With RegisterSet Do
- Begin
- DS:=OldINT24[1];
- DX:=OldINT24[2];
- AX:=$2524;
- MsDos(RegisterSet);
- End;
- OldINT24[1]:=0;
- OldINT24[2]:=0;
- End;
-
- Function INT24Result: Integer;
- Var
- I:Integer;
-
- Begin
- I:=IOResult;
- If INT24Err Then
- Begin
- I:=I+256*INT24ErrCode;
- INT24On;
- End;
- INT24Result:=I;
- End;
- { INT24Result returns all the regular Turbo IOResult codes if no critical
- error has occurred. If a critical error, then the following values are
- added to the error code from Turbo (each is 256 times the INT24ErrorCode
- value returned by DOS):
- 256: Attempt to write on write protected disk
- 512: Unknown unit [internal dos error]
- 768: Drive not ready [drive door open or bad drive]
- 1024: Unknown command [internal dos error]
- 1280: Data error (CRC) [bad sector or drive]
- 1536: Bad request structure length [internal dos error]
- 1792: Seek error [bad disk or drive]
- 2048: Unknown media type [bad disk or drive]
- 2304: Sector not found [bad disk or drive]
- 2560: Printer out of paper [anything that the printer might signal]
- 2816: Write fault [character device not ready]
- 3072: Read fault [character device not ready]
- 3328: General failure [several meanings]
-
- If you need the IOResult part, use
- I:=INT24Result and 255; [masks out the INT 24 code]
-
- For the INT 24 code, use
- I:=INT24Result Shr 8; [same as Div 256, except faster]
-
- INT24Result clears both error codes, so you must assign it to a variable if
- you want to extract both codes:
- J:=INT24Result;
- WriteLn('Turbo IOResult = ',J And 255);
- WriteLn('DOS INT 24 code = ',J Shr 8); }
-
- { Main program. Delete next line to enable }
- (**)
-
- { Run this with printer off (or no printer), and nothing in drive A }
-
- Var
- F: File;
- I: Integer;
-
- Procedure PrinterTest;
- Begin
- WriteLn(LST,'test');
- I:=INT24Result;
- If I<>0 Then WriteLn('Printer error: ',I)
- Else WriteLn('Printer OK');
- End;
-
- Procedure FileTest;
- Begin
- Assign(F,'A:FILE');
- {$I-} Reset(F); {$I+}
- I:=INT24Result;
- If I<>0 Then WriteLn('Open failure on A:FILE : INT24Result=',I)
- Else WriteLn('A:FILE exists');
- Close(F);
- End;
-
- Begin
- INT24On;
- PrinterTest;
- FileTest;
- PrinterTest;
- INT24Off;
- FileTest;
- PrinterTest;
- End.
- (**)